package dk.muldbjergskolen.db;

import dk.muldbjergskolen.model.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;

public class LektionDB {
	
	private ConnectionDB connDB;

	public LektionDB()
	{
		connDB = ConnectionDB.getInstance();
	}
	
	/**
	 * Opretter en lektion i databasen.
	 * @param lektion	som skal oprettes.
	 * @throws SQLException
	 */
	public void opretLektion(Lektion lektion) throws SQLException
	{
		// Konverter fra java datetime til sql datetime.
		java.sql.Date sqlDato = new java.sql.Date(lektion.getDato().getTime());
		
		// Del-query der afgør, om der skal bookes lokale eller inventar.
		String bookingTypeQuery = null;
		if (lektion.getLokale() == null)
			bookingTypeQuery = " (SELECT id FROM Inventar WHERE navn = '" + lektion.getInventar().getNavn() + "'), NULL ";
		else
			bookingTypeQuery = " NULL, (SELECT id FROM Lokale WHERE navn = '"+lektion.getLokale().getNavn()+"') ";
		
		String query = "INSERT INTO Lektion (dato, tidsIntervalId, formaal, bookerAnsatId, inventarId, lokaleId)" +
				" values ('"+sqlDato+"', "+lektion.getTidsInterval().getId()+", '"+lektion.getFormaal()+"'," +
						"(SELECT personId FROM Ansat WHERE brugernavn = '"+lektion.getBooker().getBrugernavn()+"')," +
						bookingTypeQuery + ")";
		
		try
    	{
    		connDB.execQuery(query);
    	}
    	catch (SQLException e)
    	{
    		throw e;
    	}
	}
	
	/**
	 * Sletter en eksisterende booking i databasen.
	 * @param lektion	som skal slettes.
	 * @throws SQLException
	 */
	public void sletLektion(Lektion lektion) throws SQLException
	{
		// Konverter fra java datetime til sql datetime.
		java.sql.Date sqlDato = new java.sql.Date(lektion.getDato().getTime());
		
		// Afgør om den skal slette bookede lokaler eller inventar.
		String lokaleIsNull = null;
		if (lektion.getLokale() == null)
			lokaleIsNull = "IS NULL";
		else
			lokaleIsNull = "IS NOT NULL";
		
		String query = "DELETE FROM Lektion WHERE dato = '"+sqlDato+"' AND tidsIntervalId = '"+lektion.getTidsInterval().getId()+"' AND lokaleId " + lokaleIsNull;

		connDB.execQuery(query);
		
		try
    	{
    		connDB.execQuery(query);
    	}
    	catch (SQLException e)
    	{
    		throw e;
    	}
	}
	
	/**
	 * Finder alle lektioner mellem tó datoer for et lokale.
	 * @param fraDato
	 * @param tilDato
	 * @param lokale
	 * @return
	 */
	public ArrayList<Lektion> findLektioner(Date fraDato, Date tilDato, Lokale lokale)
	{
		return findLektioner(fraDato, tilDato, lokale, null);
	}
	
	/**
	 * Finder alle lektioner mellem tó datoer, som et inventar er booket til.
	 * @param fraDato
	 * @param tilDato
	 * @param inventar
	 * @return
	 */
	public ArrayList<Lektion> findLektioner(Date fraDato, Date tilDato, Inventar inventar)
	{
		return findLektioner(fraDato, tilDato, null, inventar);
	}
	
	/**
	 * Finder alle lektionerne ud fra enten et lokale eller inventar.
	 * @param fraDato
	 * @param tilDato
	 * @param lokale
	 * @param inventar
	 * @return
	 */
	private ArrayList<Lektion> findLektioner(Date fraDato, Date tilDato, Lokale lokale, Inventar inventar)
	{
		java.sql.Date sqlFraDato = new java.sql.Date(fraDato.getTime());
		java.sql.Date sqlTilDato = new java.sql.Date(tilDato.getTime());
		
		ArrayList<Lektion> lektioner = new ArrayList<Lektion>();
		
		// Afgør om det er lokale eller inventar der skal findes.
		String query;
		if (lokale != null && inventar == null)
		{
			query = "SELECT dato, tidsIntervalId, formaal, bookerAnsatId, inventarId, lokaleId FROM Lektion" +
					" WHERE lokaleId = "+lokale.getId()+" AND dato >= '"+sqlFraDato+"' AND dato <= '"+sqlTilDato+"'";
		}
		else if (inventar != null && lokale == null)
		{
			query = "SELECT dato, tidsIntervalId, formaal, bookerAnsatId, inventarId, lokaleId FROM Lektion" +
					" WHERE inventarId = "+inventar.getId()+" AND dato >= '"+sqlFraDato+"' AND dato <= '"+sqlTilDato+"'";
		}
		else
		{
			throw new Error("LektionDB.findLektioner: Enten lokale eller inventar skal være null, men ikke begge.");
		}
		
		try
		{
			ResultSet rs = connDB.getResultSet(query);
			
			while(rs.next())
			{
				lektioner.add(buildLektion(rs));		
			}
			rs.close();
		}
		catch(SQLException e)
		{
			System.out.println(e.getMessage());
		}
		
		return lektioner;
	}
	
	/**
	 * Laver et lektion objekt ud fra et result set.
	 * @param result ResultSet som lektion objektet skal laves ud fra.
	 * @return	et lektion objekt.
	 * @throws SQLException
	 */
	private Lektion buildLektion(ResultSet result) throws SQLException
	{
		Lektion b = null;
		
		// Tjek om det er et lokale eller inventar.
		if (result.getInt("lokaleId") != 0)
		{
			Lokale l = new LokaleDB().getLokale(result.getInt("lokaleId"));
			
			b = new Lektion(result.getDate("dato"),
					new TidsIntervalDB().getTidsInterval(result.getInt("tidsIntervalId")),
					result.getString("formaal"),
					new AnsatDB().getAnsat(result.getInt("bookerAnsatId")),
					l);
		}
		else
		{
			Inventar i = new InventarDB().getInventar(result.getInt("inventarId"));
			
			b = new Lektion(result.getDate("dato"),
					new TidsIntervalDB().getTidsInterval(result.getInt("tidsIntervalId")),
					result.getString("formaal"),
					new AnsatDB().getAnsat(result.getInt("bookerAnsatId")),
					i);
		}
		
		return b;
	}
}

